home *** CD-ROM | disk | FTP | other *** search
- * I/O Opcode 3 - WRITE
- *
- * This routine will store a record into the file buffer providing
- * the file has been open for writing. If the buffer is full, it
- * will call FLUSH to write it out to disk and then start a new
- * buffer.
- *
-
- WRITE0 ANDI R12,>FF00
- AI R12,24
- LDCR @B02,4 Select RAM bank 2
- BLWP @IFO See if file is open
- JEQ WRITE2
-
- WRITE1 BL @DSRERR
- DATA >0700 File error
-
- * If the file is open for input mode, error. All other modes
- * allow write access.
- WRITE2 CB @56(R5),@B02 Input mode
- JNE WRITE3
- BL @DSRERR
- DATA >0200 Bad open attribute?
-
- * Now check to see if we're doing sequential or random I/O
-
- WRITE3 LDCR @ZERO,4
- MOVB @PABBUF+1,R1
- ANDI R1,>0100
- JEQ WRITE4
-
- * We're handling relative I/O now! 7-2-95
-
- B @WRIT50
-
- * The first thing we do is see if we're working on an AU. If
- * not, we assume this is the first record being written to this
- * file. If the data chain is empty, we allocate an AU for it.
- * Otherwise, we use the AU that's already allocated.
-
- WRITE4 LDCR @B02,4 Select RAM bank 2
- C @50(R5),@ZERO See if current AU=0
- JEQ WRT4Z
- B @WRIT10
- WRT4Z
- * Let's see if this file has any AU's allocated for it already.
- *
- MOV @4(R5),R1 Get FDR address
- LDCR @2(R5),4 Select bank with FDR
- MOV @40(R1),R7 Get 1st AU in chain
- JEQ WRIT4A
- LDCR @B02,4
- MOV R7,@50(R5) Save the AU
-
- * If we're in update mode and the file has fixed length records,
- * we should read in the data to the buffer.
-
- CB @ZERO,@56(R5) See if update mode
- JNE WRIT6B
- LDCR @2(R5),4
- MOVB @12(R1),R0 Get file flags
- ANDI R0,8000
- JNE WRIT6B
- LDCR @B04,4 We have to read it in!
- MOV R6,R3
- SRL R3,8
- SLA R3,1
- MPY @SAUTBL(R3),R7
- LI R3,SECBUF
- SRL R8,1
- JNC WRT4A
- AI R3,>100
- WRT4A SRL R7,1
- JNC WRT4B
- AI R8,>8000
- WRT4B LDCR @ZERO,4
- BLWP @BANKIT
- DATA SCSIRD
- JEQ WRT4C
- BL @DSRERR
- DATA >0600 Device error
-
- WRT4C LDCR @B02,4
- MOV @6(R5),R7 Get Buffer address
- MOVB @3(R5),R8 Get buffer bank
- WRT4D LDCR @ZERO,4
- MOV *R3+,R0
- LDCR R8,4
- MOV R0,*R7+
- CI R3,SECBUF+512
- JNE WRT4D
- JMP WRIT6B
-
- * OK. Let's go out and allocate the 1st AU for the file
-
- WRIT4A MOV R5,R0 Save pointer to cache entry
-
- CLR R7 No preferred starting AU
- LI R8,1 We want 1 AU
- LI R3,256*8 AU boundry
- LDCR @ZERO,4 Select RAM bank 0
- BLWP @ALLOC
- JEQ WRITE5
- BL @DSRERR
- DATA >0600 Device error
-
- WRITE5 CI R4,0 Make sure we got one
- JNE WRITE6
-
- BL @DSRERR
- DATA >0400 Out of space
-
- WRITE6 LDCR @B02,4 Select RAM bank 2
- MOV R5,R2
- MOV R0,R5 Restore pointer
-
- MOV R2,@50(R5) Save current AU
-
- * Put the AU in the data chain
-
- MOV @4(R5),R1 Get pointer to FDR
- LDCR @2(R5),4
- MOV R2,@40(R1) Store AU in data chain
- MOV R2,@42(R1)
- INC @34(R1) Increment # of AU's in FDR
- LDCR @B04,4 Set # of sectors allocated
- MOV R6,R3
- SRL R3,8
- SLA R3,1
- MOV @SAUTBL(R3),R3
- LDCR @B02,4
- LDCR @2(R5),4
- MOV R3,@14(R1)
-
- WRIT6B LDCR @B02,4
- CLR @52(R5) Sector within AU = 0
- CLR @58(R5) Buffer size = 256
- MOV @6(R5),@54(R5) Pointer within buffer
-
- LDCR @2(R5),4 Select bank with FDR
-
- MOVB @12(R1),R3 If variable length records,
- ANDI R3,>8000 Set sector # to one
- JEQ WRT6A
- LI R3,1
- LDCR @B02,4
- MOV R3,@62(R5)
-
- * See if we can use a 512 byte buffer
- *
- WRT6A LDCR @B04,4 Select RAM bank 4
- MOV R6,R3
- SRL R3,8
- SLA R3,1
- MOV @SAUTBL(R3),R1
- CI R1,1
- JEQ WRITE8
- ANDI R1,>0001
- JEQ WRITE7
- ANDI R2,>0001
- JNE WRITE8
-
- WRITE7 LDCR @B02,4 Select RAM bank 2
- SETO @58(R5)
- WRITE8 B @WRIT30
-
-
- * Here we check to see if there is enough room in the buffer
- * to hold the record. In the case of variable length files,
- * we must also account for the record size byte and the
- * end of sector marker.
- *
- WRIT10 LDCR @B02,4
- MOV @4(R5),R1
- LDCR @2(R5),4
- MOVB @17(R1),R2 Get record size
- MOVB @12(R1),R4 Get file flags
-
- LDCR @ZERO,4
- CB @PABBUF+5,R2 Make sure we're not trying
- JL WRIT11 to write more characters than
- JEQ WRIT11 the file allows
-
- BL @DSRERR
- DATA >0700 File error
-
- WRIT11 SRL R2,8
- ANDI R4,>8000 Check for fixed or variable
- JEQ WRIT12
-
- MOVB @PABBUF+5,R2 Get character count from PAB
- SRL R2,8
- INCT R2 Add in length byte and EOS marker
-
- WRIT12
-
- * We will now see if there's enough room in the buffer
-
- LDCR @B02,4 Select RAM bank 2
- MOV @54(R5),R1 Get pointer within buffer
- S @6(R5),R1 Subtract the base address
- CI R1,>200
- JEQ WRIT14
- CI R1,>100
- JNE WRT12A
- C @58(R5),@ZERO See if buffer size is 256
- JEQ WRIT14 If so, read next sector
- WRT12A
- MOV @54(R5),R1
- ANDI R1,>00FF
- A R2,R1
- CI R1,>100
- JH WRIT13
- B @WRIT30
-
- * There is not enough room in the buffer to add one more
- * record. First we check to see if the buffer size is 512
- * bytes. If so, we see if we are in the first half and simply
- * adjust a couple of pointers to go to the second half of
- * the buffer. Otherwise, we write the buffer out to disk
- * and start a new one.
-
- WRIT13
-
- * If we have variable length records,
- * we want to increment our sector #
- LDCR @B02,4
- MOV @4(R5),R1 Get address of FDR
- LDCR @2(R5),4 Select bank with FDR
- MOV @12(R1),R0 Get file flags
- LDCR @B02,4 Select Bank 2 again
- ANDI R0,>8000
- JEQ WRT13A
- INC @62(R5) Increment sector #
- WRT13A
- MOV @58(R5),R1 Check for 512 byte buffer
- JEQ WRIT14
-
- MOV @54(R5),R1 Get pointer in buffer
- ANDI R1,>0100 Check what half we're in
- JNE WRIT14
-
- MOV @54(R5),R1 Just go to 2nd half of buffer
- ANDI R1,>FF00
- AI R1,>100
- MOV R1,@54(R5)
-
- B @WRIT30
-
- * Here we have to write the buffer out to disk. We then
- * go to the next sector in the AU or next AU. If there
- * are no more AU's, we have to allocate a new one and
- * put it at the end of the data chain
- *
- * If we are in update mode writing fixed length records,
- * we read the old data into the buffer.
-
- WRIT14
- BL @FLUSH
-
- LDCR @B04,4 Select RAM bank 4
- MOV R6,R3 Get number of sectors / AU
- SRL R3,8
- SLA R3,1
- MOV @SAUTBL(R3),R3
-
- LDCR @B02,4 Select RAM bank 2
- INC @52(R5) Go to next sector in AU
- MOV @6(R5),@54(R5) Reset pointer within buffer
- C @58(R5),@ZERO If buffer size is 512 bytes,
- JEQ WRIT15 then add another sector
- INC @52(R5)
- WRIT15 C @52(R5),R3 See if we need to go to next AU
- JL WRT18A
-
- S R3,@52(R5)
-
- * We now have to search the data chain to see where our
- * AU is. If it's at the end of the file, we have to
- * allocate a new AU.
-
- MOV @50(R5),R2 Get current AU
- MOV @4(R5),R1 Get FDR address
- AI R1,42 Point to data chain (+2)
- LDCR @2(R5),4
-
- WRIT16 C *R1,@ZERO Are we at the end?
- JEQ WRIT17
- C *R1,R2 Is this our AU?
- JEQ WRIT19
- AI R1,4
- JMP WRIT16
-
- WRIT17 INC R2 Just go to next AU
- WRIT18 LDCR @B02,4
- MOV R2,@50(R5)
-
- CLR @58(R5) Set buffer size to 256
- WRT18A
-
- * Here we check to see if we're in update mode
- * and have fixed length records. If so, we want
- * to read the sector first
-
- LDCR @B02,4
- CB @ZERO,@56(R5) See if update mode
- JNE WRT18F
- LDCR @2(R5),4
- MOVB @12(R1),R0 Get file flags
- ANDI R0,8000
- JNE WRT18F
- LDCR @B04,4 We have to read it in!
- MOV R6,R3
- SRL R3,8
- SLA R3,1
- MPY @SAUTBL(R3),R7
- LI R3,SECBUF
- SRL R8,1
- JNC WRT18B
- AI R3,>100
- WRT18B SRL R7,1
- JNC WRT18C
- AI R8,>8000
- WRT18C LDCR @ZERO,4
- BLWP @BANKIT
- DATA SCSIRD
- JEQ WRT18D
- BL @DSRERR
- DATA >0600 Device error
-
- WRT18D LDCR @B02,4
- MOV @6(R5),R7 Get Buffer address
- MOVB @3(R5),R8 Get buffer bank
- WRT18E LDCR @ZERO,4
- MOV *R3+,R0
- LDCR R8,4
- MOV R0,*R7+
- CI R3,SECBUF+512
- JNE WRT18E
- WRT18F B @WRIT30
-
- WRIT19 MOV @2(R1),R2 Get next AU
- JNE WRIT18
-
- * It looks like we have to allocate another AU for the
- * file. Here we go.
-
- MOV R5,R0 Save pointer
- MOV *R1,R7 Set preferred AU
- INC R7
- LI R8,1 We want 1 AU
- LI R3,256 In case we don't get the one we want
- LDCR @ZERO,4
- BLWP @ALLOC
- JEQ WRIT20
- BL @DSRERR
- DATA >0600 Device error
-
- WRIT20 CI R4,0
- JNE WRIT21
- BL @DSRERR
- DATA >0400 Out of space error
-
- WRIT21 MOV R5,R2 Save the AU
- MOV R0,R5 Restore pointer
- LDCR @B02,4
- MOV @4(R5),R8 Get FDR address
- LDCR @2(R5),4
- INC @34(R8) Increment # of AUs allocated
- LDCR @B04,4 Set # of sectors allocated
- MOV R6,R3
- SRL R3,8
- SLA R3,1
- MOV @SAUTBL(R3),R3
- LDCR @B02,4
- LDCR @2(R5),4
- A R3,@14(R8)
- C R7,R2 Did we get the AU we wanted?
- JEQ WRIT23
-
- INCT R1 If not, add a new entry to chain
- MOV R2,*R1+
- WRIT23 MOV R2,*R1
-
- LDCR @B02,4
- MOV R2,@50(R5) Store current AU
- CLR @58(R5) Set buffer size to 256
-
- * Now see if we can use a 512 byte buffer
-
- B @WRT6A
-
-
- **
- *
- * Here is the infamous WRIT30. Here is where we store the
- * record in the file buffer and set the buffer modified flag
- *
- **
-
- WRIT30 LDCR @ZERO,4
- MOVB @PABBUF+3,@VDPWA Set VDP read address to user's buffer
- NOP
- MOVB @PABBUF+2,@VDPWA
-
- LDCR @B02,4
- MOV @54(R5),R1 Get pointer in buffer
- MOV @4(R5),R2 Get FDR address
- SETO @60(R5) Set buffer modified flag
-
- * If we are doing variable length files, then we have to
- * put the byte count in first
-
- LDCR @2(R5),4 Select bank with FDR
- MOVB @12(R2),R7 Get file flags
- ANDI R7,>8000
- JEQ WRIT31
-
- LDCR @ZERO,4
- MOVB @PABBUF+5,R4 Get character count
- LDCR @B02,4
- LDCR @3(R5),4
- MOVB R4,*R1+
- JEQ WRIT34
- JMP WRIT32
-
- WRIT31 MOVB @17(R2),R4 Get fixed record size from FDR
-
- WRIT32 LDCR @B02,4
- SRL R4,8
-
- LDCR @3(R5),4 Get buffer bank swapped in
-
- WRIT33 MOVB @VDPRD,*R1+
- DEC R4
- JNE WRIT33
-
- * If we're doing variable length files, put in a new
- * end of sector marker after the record.
-
- CI R7,0
- JEQ WRIT36
- WRIT34 MOVB @B255,*R1
- MOV R1,R7 Set end of file offset
- SWPB R7
- LDCR @B02,4
- MOV @62(R5),R8 Get sector number
- SWPB R8
- LDCR @2(R5),4
- MOVB R7,@16(R2) Save end of file offset
- MOV R8,@18(R2) Save # of level 3 records
-
- WRIT35 LDCR @B02,4
- MOV R1,@54(R5) Save pointer within buffer
-
- LDCR @ZERO,4
- B @DSRRT
-
- * For fixed length files, we need to increment the record #
- * and if it's greater than the last record written, update
- * the FDR.
-
- WRIT36 LDCR @B02,4
- INC @62(R5) Increment the record #
- MOV @62(R5),R0
- MOV @4(R5),R2 Get FDR address
- LDCR @2(R5),4 Select BANK with FDR
- MOV @18(R2),R3 Get # of level 3 records written
- SWPB R3
- C R0,R3
- JL WRIT35
- SWPB R0
- MOV R0,@18(R2) Update Level 3 field in FDR
- JMP WRIT35
-
-
- **
- *
- * Here is where we handle relative I/O. If we are trying
- * to write past the end of file, we need to allocate some
- * more AUs
- *
- **
-
- WRIT50
-
- * Step 1: Make sure the file was opened for relative access
-
- LDCR @B02,4 Select RAM bank 2
- MOVB @57(R5),R0
- JNE WRIT51
-
- BL @DSRERR
- DATA >0700 File error
-
- WRIT51 LDCR @ZERO,4
- MOV @PABADR,R10 Increment record number in
- AI R10,6 caller's PAB
- ORI R10,>4000
- SWPB R10
- MOVB R10,@VDPWA
- SWPB R10
- MOVB R10,@VDPWA
- MOV @PABBUF+6,R10
- INC R10
- MOVB R10,@VDPWD
- SWPB R10
- MOVB R10,@VDPWD
-
- MOV @PABBUF+6,R10 Get record # to write
- LDCR @B02,4
- MOV @4(R5),R1 Get FDR address
- LDCR @2(R5),4
- MOV @18(R1),R2 See if we're writing past EOF
- SWPB R2
- C R10,R2
- JHE WRIT53 If so, extend the file
-
- WRIT52 BL @POSIT
- B @WRIT30
-
- WRIT53
-
- * Here we're writing past the end of the file. Let's begin
- * by computing the number of AU's that will be needed.
-
- CLR R9
- * DEC R10
- MOVB @13(R1),R0 Get # of records/sector
- MOV @34(R1),R2 Get # of AU's allocated
- SRL R0,8
- DIV R0,R9 R9 now has # of sectors needed
-
- LDCR @B04,4
- MOV R6,R3
- SRL R3,8
- SLA R3,1
- CLR R8
- DIV @SAUTBL(R3),R8 R8 now has # of AU's we need
- INC R8
- S R2,R8 Subtract the # of AU's we have
-
- WRIT54
- CI R8,0
- JNE WRIT55
- LDCR @B04,4 Get # of sectors / AU
- MOV R6,R3
- SRL R3,8
- SLA R3,1
- MOV @SAUTBL(R3),R3
-
- LDCR @ZERO,4
- MOV @PABBUF+6,R10 Update # of level 3 records
- LDCR @B02,4
- MOV @4(R5),R1 Get FDR address
- LDCR @2(R5),4
- INC R10
- SWPB R10
- MOV R10,@18(R1)
- MOV @34(R1),R7 Multiply AU's by secotrs/AU
- MPY R3,R7 to get # of sectors allocated
- MOV R8,@14(R1)
- JMP WRIT52
-
- * Here is where we allocate some more AU's for the file
-
- WRIT55
- CLR R7 No preferred starting AU
- LI R3,256 AU boundry
- LDCR @ZERO,4
- MOV R5,R0 Save R5
- BLWP @ALLOC
- JEQ WRIT56
-
- BL @DSRERR
- DATA >0600 Device error
-
- WRIT56 CI R4,0
- JNE WRIT57
- BL @DSRERR
- DATA >0400 Out of space
-
- WRIT57
- MOV R5,R2 Save starting AU
- MOV R0,R5 Restore R5
-
- * Now put the new AU's in the data chain
-
- LDCR @B02,4
- MOV @4(R5),R1 Get FDR address
- LDCR @2(R5),4
- A R4,@34(R1) Update # of AU's allocated
- S R4,R8 Subtract from # needed
- AI R1,40 Point to data chain
- WRIT58
- C *R1,@ZERO
- JEQ WRIT59
- AI R1,4
- JMP WRIT58
-
- WRIT59 DECT R1
- MOV *R1,R10
- INC R10
- C R2,R10
- JNE WRIT60
- A R4,*R1
- JMP WRIT54
-
- WRIT60 INCT R1
- MOV R2,*R1+
- MOV R2,*R1
- A R4,*R1
- DEC *R1
- JMP WRIT54
-